/**
 * Copyright (C) 2013-2014 the original author or authors.
 */
package com.foreveross.bsl.comments.application.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import com.foreveross.bsl.comments.application.CommentModuleException;
import com.foreveross.bsl.comments.application.NoticeService;
import com.foreveross.bsl.comments.application.vo.NoticeMessageVo;
import com.foreveross.bsl.comments.application.vo.NoticeVo;
import com.foreveross.bsl.comments.model.domain.Notice;
import com.foreveross.bsl.comments.model.domain.repository.NoticeRepository;
import com.foreveross.bsl.common.utils.mapper.BeanMapper;
import com.foreveross.bsl.common.utils.web.QuerySpecs;
import com.foreveross.bsl.common.utils.web.QueryOrder;
import com.foreveross.bsl.push.application.PushService;
import com.foreveross.bsl.push.application.TagSummaryService;
import com.foreveross.bsl.push.application.vo.MessageParams;
import com.foreveross.bsl.push.application.vo.ReceiverTypeEnumVo;
import com.foreveross.bsl.system.application.ApplicationRegisterApplication;
import com.google.common.collect.Maps;

/**
 * xxx
 * 
 * @author Wangyi
 * @version v1.0
 * 
 * @date 2013-7-19
 * 
 */
@Named("noticeService")
public class NoticeServiceImpl implements NoticeService {

	@Inject
	private PushService pushService;

	@Inject
	private TagSummaryService tagSumService;

	@Inject
	private NoticeConfig noticeConfig;

	@Inject
	private ApplicationRegisterApplication appRegClient;

	private final NoticeRepository getNoticeRepository() {
		return new Notice().getEntityRepository(NoticeRepository.class);
	}

	@Override
	public void add(NoticeVo notice) {
		// TODO validate
		// 先提交推送公告消息
		notice.setId(RandomStringUtils.randomAlphanumeric(16));
		notice.setCreateTime(new Date());
		String pushRequestId = pushNotice(notice);
		notice.setPushRequestId(pushRequestId);
		// 再保存公告
		Notice entity = BeanMapper.map(notice, Notice.class);
		getNoticeRepository().save(entity);
	}

	protected String pushNotice(NoticeVo notice) {
		MessageParams msgParam = this.buildMessageParams(notice);
		return pushService.submitMessage(msgParam);
	}

	private MessageParams buildMessageParams(NoticeVo notice) {
		MessageParams msgParam = new MessageParams();
		String appKey = appRegClient.getAppKeyByAppId(notice.getAppId());
		if (appKey == null) {
			throw new IllegalArgumentException("通过appId：" + notice.getAppId()
					+ "获取的appKey为空");
		}
		msgParam.setAppId(appKey);
		if (notice.hasRoles()) {
			msgParam.setReceiverType(ReceiverTypeEnumVo.TAG);
			Map<String, String> tags = Maps.newHashMap();
			tags.put(noticeConfig.getRoleKeyName(), notice.getCommaRoles());
			msgParam.setTags(tags);
		} else {
			msgParam.setReceiverType(ReceiverTypeEnumVo.APP_ID);
		}
		msgParam.setSubmitUserId(notice.getOwnerId());
		NoticeMessageVo msg = new NoticeMessageVo();
		msg.setTitle(notice.getTitle());
		msg.setContent(notice.getContent());
		msg.setNoticeId(notice.getId());
		msg.putExtra("moduleBadge", notice.isModuleBadge());
		msg.putExtra("busiDetail", notice.isBusiDetail());
		msgParam.setMessage(msg);
		return msgParam;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.comments.application.NoticeService#delete(java.lang
	 * .String)
	 */
	@Override
	public void delete(String id) {
		this.getNoticeRepository().delete(id);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.comments.application.NoticeService#find(java.lang.
	 * String, java.util.Map, org.springframework.data.domain.Pageable)
	 */
	@Override
	public Page<NoticeVo> find(int pageNumber, int pageSize,
			QuerySpecs querySpecs) {
		if (querySpecs == null) {
			querySpecs = new QuerySpecs();
		}
		if (querySpecs.getOrder("createTime") == null) {
			querySpecs.setOrder("createTime", QueryOrder.Direction.DESC);
		}
		Pageable pageable = new PageRequest(pageNumber - 1, pageSize);
		Page<Notice> page = this.getNoticeRepository().findByQuerySpecs(
				querySpecs, pageable);
		List<NoticeVo> list = BeanMapper.mapList(page.getContent(),
				NoticeVo.class);
		Page<NoticeVo> voPage = new PageImpl<NoticeVo>(list, pageable,
				page.getTotalElements());
		return voPage;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.comments.application.NoticeService#getById(java.lang
	 * .String)
	 */
	@Override
	public NoticeVo getById(String id) {
		Notice notice = this.getNoticeRepository().findOne(id);
		if (notice == null) {
			throw new CommentModuleException("不存在公告:" + id);
		}
		return BeanMapper.map(notice, NoticeVo.class);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.foreveross.bsl.comments.application.NoticeService#getRoles(java.lang
	 * .String)
	 */
	@Override
	public String[] getRoles(String appId) {
		return this.tagSumService.getTagValues(appId,
				noticeConfig.getRoleKeyName());
	}

}
